package org.geektimes.web.mvc.header.matedata;

import org.geektimes.web.mvc.header.MethodInvoke;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 处理方法信息类
 *
 * @since 1.0
 */
public class HandlerMethodInfo implements MethodInvoke {

    private  String requestPath;

    private  Method handlerMethod;

    private  Set<String> supportedHttpMethods;
    /**
     * 参数信息
     */
    private List<ParamInfo> paramInfo;
    /**
     * 响应类型
     */
    private  ResponseType responseType;

    /**
     * 目标对象
     */
    private  Object target;


    public void setRequestPath(String requestPath) {
        this.requestPath = requestPath;
    }

    public void setHandlerMethod(Method handlerMethod) {
        this.handlerMethod = handlerMethod;
    }

    public void setSupportedHttpMethods(Set<String> supportedHttpMethods) {
        this.supportedHttpMethods = supportedHttpMethods;
    }


    public void setResponseType(ResponseType responseType) {
        this.responseType = responseType;
    }

    public Object getTarget() {
        return target;
    }

    public void setTarget(Object target) {
        this.target = target;
    }


    public List<ParamInfo> getParamInfo() {
        return paramInfo;
    }

    public void setParamInfo(List<ParamInfo> paramInfo) {
        this.paramInfo = paramInfo;
    }

    public ResponseType getResponseType() {
        return responseType;
    }

    public String getRequestPath() {
        return requestPath;
    }

    public Method getHandlerMethod() {
        return handlerMethod;
    }

    public Set<String> getSupportedHttpMethods() {
        return supportedHttpMethods;
    }


    /**
     * 调用web方法
     * @param webContent
     * @return
     */
    public Object invoke(WebContent webContent) {
        //构造参数
        ///TODO 目前暂不支持文件上传，可以通过实现 ParamParse进行处理
        Object[] args = this.paramInfo
                .stream()
                .map(item -> item.getParamParse().parse(webContent, item))
                .collect(Collectors.toList())
                .toArray(new Object[]{});

        //方法调用
        try {
            return this.handlerMethod.invoke(this.target , args);
        } catch (Exception e) {
            throw new IllegalStateException(e);
        }
    }


    public enum ResponseType{
        VIEW ,JSON
    }


    @Override
    public String toString() {
        return "HandlerMethodInfo{" +
                "requestPath='" + requestPath + '\'' +
                ", handlerMethod=" + handlerMethod +
                ", supportedHttpMethods=" + supportedHttpMethods +
                ", paramInfo=" + paramInfo +
                ", responseType=" + responseType +
                ", target=" + target +
                '}';
    }
}
